<template>
  <div class="review-canvas">
    <a-alert v-if="optionalNodes.length" type="success" class="mb-2" message="通过点击节点来选择下一个审批节点">
    </a-alert>
    <div v-if="!isNull" :id="'container' + flowId" ref="canvas" class="flow-container"></div>
    <IcpEmpty v-if="isNull" />
  </div>
</template>
<script lang="ts" setup name="ReviewFlow">
import { onMounted, ref } from 'vue'
import LogicFlow from '@logicflow/core'
import { BpmnElement, BpmnAdapter, Snapshot, Control, SelectionSelect } from '@logicflow/extension'
import '@logicflow/core/dist/style/index.css'
import '@logicflow/extension/lib/style/index.css'
import startHtml from '@@/components/logicflow/registerNode/start/CustomHtml'
import userTaskHtml from '@@/components/logicflow/registerNode/userTask/CustomHtml'
import sendTaskHtml from '@@/components/logicflow/registerNode/sendTask/CustomHtml'
import endHtml from '@@/components/logicflow/registerNode/end/CustomHtml'
import selectTask from '@@/components/logicflow/registerNode/selectTask/CustomHtml'
import conditionTask from '@@/components/logicflow/registerNode/conditionTask/CustomHtml'
import { getTaskFlowDetail } from '@@/api/flow'
import customEdge from './customEdge'

const emits = defineEmits(['changeData', 'selectOptionalNodes'])
const props = defineProps({
  canvasData: {
    type: String,
    default: ''
  },
  flowId: {
    type: String,
    default: ''
  },
  hideSignSetting: {
    type: Boolean,
    defalue: false
  },
  isHttp: {
    type: Boolean,
    defalue: false
  },
  optionalNodes: {
    type: Array,
    default: () => []
  }
})

const canvas = ref()
const lf = ref()
LogicFlow.use(BpmnElement)
// LogicFlow.use(BpmnXmlAdapter)
LogicFlow.use(Snapshot)
LogicFlow.use(Control)
LogicFlow.use(SelectionSelect)
LogicFlow.use(BpmnAdapter)

// const myCanvasData = ref()

//初始化
onMounted(() => {
  if (!props.isHttp) {
    initFlowView(props.canvasData)
  } else {
    getFlowData()
  }
})

// 查询视图数据
const isNull = ref(false)
function getFlowData() {
  getTaskFlowDetail({
    taskId: props.flowId
  }).then((res: any) => {
    if (!res || !res.canvas) {
      isNull.value = true
    } else {
      isNull.value = false
    }
    const tempData = res
    const canvasData = JSON.parse(tempData.canvas)
    if (tempData.taskNodeId) {
      if (!tempData.neverWalkedList) {
        tempData.neverWalkedList = []
      }
      tempData.neverWalkedList.push(tempData.taskNodeId)
    }
    canvasData.nodes.forEach((node: any) => {
      console.log('optionalNodes', props.optionalNodes)
      if (props.optionalNodes && props.optionalNodes.length) {
        node.properties.optionalNodes = props.optionalNodes
      }
      // props.taskInfo.taskStatus !== TaskStatusEnum.completed
      if ((tempData.neverWalkedList || []).includes(node.id)) {
        node.properties.isFinished = false
      } else {
        node.properties.isFinished = true
      }
      // && props.taskInfo.taskStatus !== TaskStatusEnum.completed
      if (tempData.taskNodeId === node.id) {
        node.properties.isCurrentNode = true
      }
    })
    ;(tempData.nextNodeInfoVOList || []).forEach((item: any) => {
      const currNode = canvasData.nodes.find((node: any) => node.id === item.nodeId)
      if (currNode) {
        if (item.approvalParamType === 'PRE') {
          currNode.properties['flowable:candidateUsers'] = item.approvalParamValue.join(',')
          currNode.properties['flowable:candidateUsersName'] = item.approvalParamName
        } else {
          currNode.properties['flowable:candidateGroups'] = item.approvalParamValue.join(',')
          currNode.properties['flowable:candidateGroupsName'] = item.approvalParamName
        }
      }
    })
    initFlowView(JSON.stringify(canvasData))
  })
}

// 初始化视图
function initFlowView(data) {
  lf.value = new LogicFlow({
    container: document.querySelector('#container' + props.flowId) as HTMLElement,
    isSilentMode: true,
    hoverOutline: false,
    grid: {
      size: 10,
      visible: true,
      type: 'mesh',
      config: {
        color: '#ababab',
        thickness: 1
      }
    }
  })
  lf.value.extension.control.removeItem('undo') // 去掉上一步
  lf.value.extension.control.removeItem('redo') // 去掉下一步
  lf.value.register(userTaskHtml)
  lf.value.register(conditionTask)
  lf.value.register(sendTaskHtml)
  lf.value.register(startHtml)
  lf.value.register(endHtml)
  lf.value.register(selectTask)
  lf.value.register(customEdge)
  lf.value.setDefaultEdgeType('customEdge')
  const canvasData = JSON.parse(data)
  if (props.hideSignSetting) {
    ;(canvasData?.nodes || []).forEach((item) => {
      if (item.type === 'userTask') {
        item.properties.hideSignSetting = props.hideSignSetting
      }
    })
  }
  canvasData.nodes.forEach((node: any) => {
    if (props.optionalNodes && props.optionalNodes.length) {
      node.properties.optionalNodes = props.optionalNodes
    }
  })
  ;(canvasData?.edges || []).forEach((item) => {
    item.type = 'customEdge'
  })
  console.log('canvasData', canvasData)
  lf.value.renderRawData(canvasData)
  //绑定事件
  const { eventCenter } = lf.value.graphModel
  bindEvent(eventCenter)
}

const bindEvent = (eventCenter) => {
  eventCenter.on('changeData', (args) => {
    const defaultDate = lf.value.getProperties(args.id)
    lf.value.setProperties(args.id, parseData(Object.assign(defaultDate, memberChange(args))))
    emits('changeData', args)
  })
  eventCenter.on('selectOptionalNode', ({ nodeId, edgeId, currNodeId }) => {
    // 获取以上一节点为起点的所有边
    const edges = lf.value.graphModel.getNodeOutgoingEdge(nodeId)
    // 将上一节点出来的边都关闭动画
    edges.forEach((item) => {
      lf.value.closeEdgeAnimation(item.id)
    })
    // 开启以当前节点为终点的边动画
    lf.value.openEdgeAnimation(edgeId)
    // 返回已选的节点
    emits('selectOptionalNodes', currNodeId)
  })
}
const memberChange = (data) => {
  const temArr = (data.memberList || []).map((el) => el.value)
  const temNameArr = (data.memberList || []).map((el) => el.label)
  const param: any = {}
  if (data.personLiableType === 0) {
    param.candidateUsers = temArr.join(',')
    param.candidateUsersShow = temArr.join(',')
    param.candidateUsersName = temNameArr.join(',')
    param.candidateGroups = ''
    param.candidateGroupsShow = ''
    param.candidateGroupsName = ''
  } else {
    param.candidateGroups = temArr.join(',')
    param.candidateGroupsShow = temArr.join(',')
    param.candidateGroupsName = temNameArr.join(',')
    param.candidateUsers = ''
    param.candidateUsersShow = ''
    param.candidateUsersName = ''
  }
  return param
}
const parseData = (data) => {
  const defaultAttr = ['id', 'name', 'documentation', 'multiInstanceLoopCharacteristics']
  const nData = {}
  if (Object.keys(data).length > 0) {
    for (const key in data) {
      if (!defaultAttr.includes(key)) {
        nData[key.includes('flowable:') ? key : 'flowable:' + key] = data[key]
      } else {
        nData[key] = data[key]
      }
    }
  }
  return nData
}
</script>
<style lang="less" scoped>
.review-canvas {
  // width: 100%;
  height: 100%;
  // position: relative;
  // margin: 0px;
  // display: flex;
  overflow: hidden;

  .flow-container {
    min-width: 900px;
    height: 500px
    // display: flex;
    // flex-grow: 1; /*铺满剩余空间*/
    // border: 3px solid #ababab;
    // overflow: hidden;
  }
}

.full-card{
  .flow-container {
    height: 100%
  }
}
</style>
